package com.xcx.services.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.xcx.bo.*;
import com.xcx.common.dto.base.BaseDto;
import com.xcx.common.dto.base.BaseResp;
import com.xcx.common.dto.req.QueryUserBindingReq;
import com.xcx.common.dto.req.SaveUserInfoReq;
import com.xcx.common.dto.req.UserLoginReq;
import com.xcx.common.dto.resp.QueryUserBindingResp;
import com.xcx.common.dto.resp.UserLoginResp;
import com.xcx.common.enums.CommConfigParamKeyEnum;
import com.xcx.common.enums.IsValidEnum;
import com.xcx.common.services.CalculatorService;
import com.xcx.common.services.common.CommConfigService;
import com.xcx.common.services.common.CommUserService;
import com.xcx.common.utils.*;
import com.xcx.dao.CalcuSkinDao;
import com.xcx.dao.CalcuSkinInfoDao;
import com.xcx.dao.CalcuSkinSoundDao;
import com.xcx.dao.CalcuUnlockDao;
import com.xcx.dto.*;
import com.xcx.dto.vo.CalcuSkinDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@Component
public class CalculatorServiceImpl implements CalculatorService {


    @Autowired
    private CalcuSkinSoundDao calcuSkinSoundDao;

    @Autowired
    private CalcuSkinDao calcuSkinDao;

    @Autowired
    private CalcuUnlockDao calcuUnlockDao;

    @Autowired
    private CalcuSkinInfoDao calcuSkinInfoDao;

    @Reference
    private CommUserService commUserService;

    @Reference
    private CommConfigService commConfigService;

    @Value("${wx.appId}")
    private String wxAppId;

    @Value("${wx.appSecret}")
    private String wxAppSecret;

    @Override
    public String queryUserCalcuSet(String reqStr) {
        return null;
    }

    @Override
    public String queryCalcuSkinList(String reqStr) {
        log.info("queryCalcuSkinList.req:{}", reqStr);
        QueryCalcuSkinListResp queryCalcuSkinListResp = new QueryCalcuSkinListResp();
        try {
            CheckParamUtils.validateReqString(reqStr);
            QueryUserCalcuSkinReq baseReq = BaseDto.fromJson(reqStr, QueryUserCalcuSkinReq.class);
            CheckParamUtils.validateReqGson(baseReq);
            List<CalcuSkin> calcuSkinList = calcuSkinDao.selectByExample(new CalcuSkinExample());
            List<CalcuSkinDto> calcuSkinDtoList = new ArrayList<CalcuSkinDto>();
            if (CollectionUtils.isNotEmpty(calcuSkinList)) {
                CalcuSkinDto calcuSkinDto;
                for (CalcuSkin calcuSkin : calcuSkinList) {
                    calcuSkinDto = new CalcuSkinDto();
                    BeanUtils.copyProperties(calcuSkin, calcuSkinDto);
                    CalcuUnlock calcuUnlock = queryUnlock(baseReq.getUserNo(), calcuSkin.getSkinNo());
                    if (calcuUnlock == null) {
                        calcuSkinDto.setIsUnlock(IsValidEnum.VALID_NO.getCode());
                    } else {
                        calcuSkinDto.setIsUnlock(calcuUnlock.getIsUnlock());
                    }
                    calcuSkinDtoList.add(calcuSkinDto);
                }
            }
            queryCalcuSkinListResp.buildDefaultSuccessResp(baseReq);
            queryCalcuSkinListResp.setCalcuSkinList(calcuSkinDtoList);
        } catch (Exception e) {
            ExceptionUtils.buildExceptionResp("CalculatorServiceImpl", reqStr, queryCalcuSkinListResp, e.getMessage(), e);
        }
        log.info("queryCalcuSkinList.resp:{}", queryCalcuSkinListResp.toString());
        return queryCalcuSkinListResp.toString();
    }

    @Override
    public String updateCalcuSkin(String reqStr) {
        log.info("updateCalcuSkin.req:{}", reqStr);
        BaseResp baseResp = new BaseResp();
        try {
            CheckParamUtils.validateReqString(reqStr);
            UpdateCalcuSkinReq baseReq = BaseDto.fromJson(reqStr, UpdateCalcuSkinReq.class);
            CheckParamUtils.validateReqGson(baseReq);
            CalcuSkinSoundExample example = new CalcuSkinSoundExample();
            example.createCriteria().andUserNoEqualTo(baseReq.getUserNo());
            example.createCriteria().andStatusEqualTo(IsValidEnum.VALID_YES.getCode());
            List<CalcuSkinSound> calcuSkinSoundList = calcuSkinSoundDao.selectByExample(example);
            if (CollectionUtils.isEmpty(calcuSkinSoundList)) {
                CalcuSkinSound calcuSkinSound = new CalcuSkinSound();
                calcuSkinSound.setSkinSoundNo(IdGenUtils.uuid());
                calcuSkinSound.setUserNo(baseReq.getUserNo());
                ;
                calcuSkinSound.setSkinNo(baseReq.getSkinNo());
                calcuSkinSound.setStatus(IsValidEnum.VALID_YES.getCode());
                calcuSkinSoundDao.insert(calcuSkinSound);
            } else {
                CalcuSkinSoundExample exampleUp = new CalcuSkinSoundExample();
                exampleUp.createCriteria().andUserNoEqualTo(baseReq.getUserNo());
                exampleUp.createCriteria().andStatusEqualTo(IsValidEnum.VALID_YES.getCode());
                CalcuSkinSound calcuSkinSoundUp = new CalcuSkinSound();
                calcuSkinSoundUp.setSkinNo(baseReq.getSkinNo());
                calcuSkinSoundDao.updateByExampleSelective(calcuSkinSoundUp, exampleUp);
            }
            baseResp.buildDefaultSuccessResp(baseReq);
        } catch (Exception e) {
            ExceptionUtils.buildExceptionResp("CalculatorServiceImpl", reqStr, baseResp, e.getMessage(), e);
        }
        log.info("updateCalcuSkin.resp:{}", baseResp.toString());
        return baseResp.toString();
    }

    @Override
    public String queryUserCalcuSkin(String reqStr) {
        log.info("queryUserCalcuSkin.req:{}", reqStr);
        QueryUserCalcuSkinResp baseResp = new QueryUserCalcuSkinResp();
        try {
            CheckParamUtils.validateReqString(reqStr);
            QueryUserCalcuSkinReq baseReq = BaseDto.fromJson(reqStr, QueryUserCalcuSkinReq.class);
            CheckParamUtils.validateReqGson(baseReq);
            CalcuSkinSoundExample example = new CalcuSkinSoundExample();
            example.createCriteria().andUserNoEqualTo(baseReq.getUserNo());
            example.createCriteria().andStatusEqualTo(IsValidEnum.VALID_YES.getCode());
            List<CalcuSkinSound> calcuSkinSoundList = calcuSkinSoundDao.selectByExample(example);
            if (CollectionUtils.isNotEmpty(calcuSkinSoundList)
                    && calcuSkinSoundList.get(0) != null
                    && StringUtils.isNotBlank(calcuSkinSoundList.get(0).getSkinNo())) {
                CalcuSkinExample calcuSkinExample = new CalcuSkinExample();
                calcuSkinExample.createCriteria().andSkinNoEqualTo(calcuSkinSoundList.get(0).getSkinNo())
                        .andSkinStatusEqualTo(IsValidEnum.VALID_YES.getCode());
                List<CalcuSkin> calcuSkinList = calcuSkinDao.selectByExample(calcuSkinExample);
                if (CollectionUtils.isNotEmpty(calcuSkinList)
                        && calcuSkinList.get(0) != null
                        && StringUtils.isNotBlank(calcuSkinList.get(0).getSkinInfoNo())) {
                    CalcuSkinInfoExample calcuSkinInfoExample = new CalcuSkinInfoExample();
                    calcuSkinInfoExample.createCriteria().andSkinInfoNoEqualTo(calcuSkinList.get(0).getSkinInfoNo());
                    List<CalcuSkinInfo> calcuSkinInfoList = calcuSkinInfoDao.selectByExample(calcuSkinInfoExample);
                    if (CollectionUtils.isNotEmpty(calcuSkinInfoList)
                            && calcuSkinInfoList.get(0) != null) {
                        baseResp.setCalcuSkinInfo(calcuSkinInfoList.get(0));
                    }
                }
            }
            baseResp.buildDefaultSuccessResp(baseReq);
        } catch (Exception e) {
            ExceptionUtils.buildExceptionResp("CalculatorServiceImpl", reqStr, baseResp, e.getMessage(), e);
        }
        log.info("queryUserCalcuSkin.resp:{}", baseResp.toString());
        return baseResp.toString();
    }

    @Override
    public String userLogin(String reqStr) {
        log.info("userLogin.req:{}", reqStr);
        UserLoginResp baseResp = new UserLoginResp();
        try {
            CheckParamUtils.validateReqString(reqStr);
            UserLoginReq baseReq = BaseDto.fromJson(reqStr, UserLoginReq.class);
            baseReq.setAppId(wxAppId);
            baseReq.setSecret(wxAppSecret);
            CheckParamUtils.validateReqGson(baseReq);
            baseResp = commUserService.userLogin(baseReq);
            if (baseResp.isSuccess()) {
            	baseResp.buildDefaultSuccessResp(baseReq);
			}
        } catch (Exception e) {
            ExceptionUtils.buildExceptionResp("userLogin", reqStr, baseResp, e.getMessage(), e);
        }
        log.info("userLogin.resp:{}", baseResp.toString());
        return baseResp.toString();
    }

    @Override
    public String queryUserBinding(String reqStr) {
        log.info("queryUserBinding.req:{}", reqStr);
        QueryUserBindingResp queryUserBindingResp = new QueryUserBindingResp();
        try {
            CheckParamUtils.validateReqString(reqStr);
            QueryUserBindingReq queryUserBindingReq = BaseDto.fromJson(reqStr, QueryUserBindingReq.class);
            CheckParamUtils.validateReqGson(queryUserBindingReq);
            queryUserBindingResp = commUserService.queryUserBinding(queryUserBindingReq);
        } catch (Exception e) {
            ExceptionUtils.buildExceptionResp("CalculatorServiceImpl", reqStr, queryUserBindingResp, e.getMessage(), e);
        }
        log.info("queryUserBinding.resp:{}", queryUserBindingResp.toString());
        return queryUserBindingResp.toString();
    }

    @Override
    public String saveUserInfo(String reqStr) {
        log.info("saveUserInfo.req:{}", reqStr);
        BaseResp baseResp = new BaseResp();
        try {
            CheckParamUtils.validateReqString(reqStr);
            SaveUserInfoReq saveUserInfoReq = BaseDto.fromJson(reqStr, SaveUserInfoReq.class);
            CheckParamUtils.validateReqGson(saveUserInfoReq);
            baseResp = commUserService.saveUserInfo(saveUserInfoReq);
			if (baseResp.isSuccess()) {
            	baseResp.buildDefaultSuccessResp(saveUserInfoReq);
			}
        } catch (Exception e) {
            ExceptionUtils.buildExceptionResp("CalculatorServiceImpl", reqStr, baseResp, e.getMessage(), e);
        }
        log.info("saveUserInfo.resp:{}", baseResp.toString());
        return baseResp.toString();
    }


    /**
     * 查询用户是否解锁
     *
     * @param reqStr
     * @return
     */
    @Override
    public String queryUserUnlock(String reqStr) {
        log.info("queryUserUnlock.req:{}", reqStr);
        QueryUserUnlockResp baseResp = new QueryUserUnlockResp();
        try {
            CheckParamUtils.validateReqString(reqStr);
            UpdateCalcuSkinReq baseReq = BaseDto.fromJson(reqStr, UpdateCalcuSkinReq.class);
            CheckParamUtils.validateReqGson(baseReq);

            //判断用户是否解锁
            CalcuUnlock calcuUnlock = queryUnlock(baseReq.getUserNo(), baseReq.getSkinNo());
            if (calcuUnlock != null) {
                baseResp.setIsUnlock(calcuUnlock.getIsUnlock());
            } else {
                baseResp.setIsUnlock(IsValidEnum.VALID_NO.getCode());
            }

            baseResp.buildDefaultSuccessResp(baseReq);
        } catch (Exception e) {
            ExceptionUtils.buildExceptionResp("CalculatorServiceImpl", reqStr, baseResp, e.getMessage(), e);
        }
        log.info("queryUserUnlock.resp:{}", baseResp.toString());
        return baseResp.toString();
    }

    /**
     * 保存更新用户分享次数
     *
     * @param reqStr
     * @return
     */
    @Override
    public String updateUserShare(String reqStr) {
        log.info("updateUserShare.req:{}", reqStr);
        RecordUserShareResp baseResp = new RecordUserShareResp();
        try {
            CheckParamUtils.validateReqString(reqStr);
            RecordUserShareReq baseReq = BaseDto.fromJson(reqStr, RecordUserShareReq.class);
            CheckParamUtils.validateReqGson(baseReq);
            //判断用户是否解锁
            CalcuUnlock calcuUnlock = queryUnlock(baseReq.getUserNo(), baseReq.getSkinNo());
            if (calcuUnlock == null) {
                calcuUnlock = new CalcuUnlock();
                calcuUnlock.setUnlockId(IdGenUtils.uuid());
                calcuUnlock.setUserNo(baseReq.getUserNo());
                calcuUnlock.setSkinNo(baseReq.getSkinNo());
                calcuUnlock.setShareTicket(baseReq.getShareTicket());
                calcuUnlock.setIsUnlock("0");
                calcuUnlock.setOnLoad(1);
                calcuUnlockDao.insert(calcuUnlock);
            } else {
                if (calcuUnlock.getShareTicket().contains(baseReq.getShareTicket())) {
                    baseResp.setOnLoad(calcuUnlock.getOnLoad());
                    baseResp.setIsUnlock(IsValidEnum.VALID_NO.getCode());
                    baseResp.setShareAgain(IsValidEnum.VALID_YES.getCode());
                } else {
                    calcuUnlock.setOnLoad(calcuUnlock.getOnLoad() + 1);
                    String maxShareNum = commConfigService.queryParamValue(CommConfigParamKeyEnum.CALCULATOR_MAX_SHARE_NUM);
                    if (calcuUnlock.getOnLoad() >= Integer.parseInt(maxShareNum)) {
                        calcuUnlock.setIsUnlock(IsValidEnum.VALID_YES.getCode());
                        baseResp.setIsUnlock(IsValidEnum.VALID_YES.getCode());
                    } else {
                        calcuUnlock.setIsUnlock(IsValidEnum.VALID_NO.getCode());
                        baseResp.setIsUnlock(IsValidEnum.VALID_NO.getCode());
                    }
                    calcuUnlockDao.updateByPrimaryKeySelective(calcuUnlock);
                }
            }

            baseResp.setOnLoad(calcuUnlock.getOnLoad());
            baseResp.buildDefaultSuccessResp(baseReq);
        } catch (Exception e) {
            ExceptionUtils.buildExceptionResp("CalculatorServiceImpl", reqStr, baseResp, e.getMessage(), e);
        }
        log.info("updateUserShare.resp:{}", baseResp.toString());
        return baseResp.toString();
    }

    private CalcuUnlock queryUnlock(String userNo, String skinNo) {
        CalcuUnlockExample example = new CalcuUnlockExample();
        example.createCriteria()
                .andUserNoEqualTo(userNo)
                .andSkinNoEqualTo(skinNo);
        List<CalcuUnlock> lst = calcuUnlockDao.selectByExample(example);
        return CollectionsUtils.isEmpty(lst) && lst.size() == 0 ? null : lst.get(0);
    }

}
